package com.three.mahjong.base.model;

import com.three.mahjong.base.rule.MJBaseHuPaiRule;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.three.mahjong.base.model.CardSmallType.*;


/**
 * 牌型
 */
public enum HandPattern {

    /**
     * 爆和(封顶以内的牌型番种)
     */
    JI_HU(0) {// 鸡湖

        /**
         * 0番1分
         * 什么牌都可以和，就像推倒和规则。
         * 一到六万、三个一筒、四到六筒，两个二索
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    PING_HU(1) {// 平胡

        /**
         * 1番2分
         * 全部都是顺子而没有刻子。
         * 一二三索、四到九万、四到六筒、两个二索
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    PENG_PENG_HU(2) {// 碰碰胡

        /**
         * 3番8分
         * 全部是刻子，没有顺子。
         * 三个一索、三个四万、三个七万、三个四筒、两个二索
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    HUN_YI_SE(3) {// 混一色

        /**
         * 3番8分
         * 整副牌由字牌及另外单一花色（筒、条或万）组成。
         * 一万到九万、一万到三万、两个中
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    HUN_PENG(4) {// 混碰

        /**
         * 5番32分
         * 混一色+碰碰胡
         * 三个一万、三个四万、三个七万、三个两万、两个中
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    QING_YI_SE(5) {// 清一色

        /**
         * 5番32分
         * 整副牌由同一花色组成。
         * 一万、二万、三万、四万、五万、六万、七万、八万、九万、一万、二万、三万、九万、九万
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    /**
     * 爆和意外的牌型(特殊牌型)
     */
    QING_PENG(6) {// 清碰

        /**
         * 6番64分
         * 清一色加碰碰胡
         * 三个一万、三个二万、三个四万、三个七万、两个九万
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    HUN_YAO_JIU(7) {// 混幺九

        /**
         * 6番64分
         * 由幺九牌和字牌组成的牌型。
         * 三个一万、三个九万、三个一索、三个一筒、二个中
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return false;
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return null;
        }
    },
    XIAO_SAN_YUAN(8) {// 小三元

        /**
         * 7番128分
         * 拿齐中、发、白三种三元牌，但其中一种是将。
         * 三个一万、顺子、三发、三白、二中
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return MJBaseHuPaiRule.isXiaoSanYuan(cards, getPaiXing());
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return new HashSet<>(
                    Arrays.asList(
                            ZHONG,// 中
                            FA,// 发
                            BAI// 白
                    )
            );
        }
    },
    XIAO_SI_XI(9) {// 小四喜

        /**
         * 7番128分
         * 胡牌者完成东、南、西、北其中三组刻子，一组对子。
         * 顺子+三东、三南、三西、2北
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return MJBaseHuPaiRule.isXiaoSiXi(cards, getPaiXing());
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return new HashSet<>(
                    Arrays.asList(
                            DONG_FENG,// 东风
                            XI_FENG,// 西风
                            NAN_FENG,// 南风
                            BEI_FENG// 北风
                    )
            );
        }
    },
    ZI_YI_SE(10) {// 字一色

        /**
         * 8番256分
         * 七只字牌组合成的清一色。
         * 三东、三西、三南、三白、二中
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return MJBaseHuPaiRule.isZiYiSe(cards, getPaiXing());
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return new HashSet<>(
                    Arrays.asList(
                            DONG_FENG,// 东风
                            XI_FENG,// 西风
                            NAN_FENG,// 南风
                            BEI_FENG,// 北风
                            ZHONG,// 中
                            FA,//发
                            BAI// 白
                    )
            );
        }
    },
    QING_YAO_JIU(11) {// 清幺九

        /**
         * 8番256分
         * 只由幺九两种牌组成的牌型。
         * 三个一万、三个九万、三个一索、三个一筒、三个九筒
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return MJBaseHuPaiRule.isQingYaoJiu(cards, getPaiXing());
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return new HashSet<>(
                    Arrays.asList(
                            YI_WAN,// 一万
                            JIU_WAN, // 九万
                            YI_SUO, // 一索
                            JIU_SUO,// 九索
                            YI_TONG, // 一筒
                            JIU_TONG// 九筒
                    )
            );
        }
    },
    DA_SAN_YUAN(12) {// 大三元

        /**
         * 9番512分
         * 胡牌时，有中、发、白三组刻子。
         * 三个中、发、白+一对+碰/吃
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return MJBaseHuPaiRule.isDaSanYuan(cards, getPaiXing());
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return new HashSet<>(
                    Arrays.asList(
                            ZHONG,// 中
                            FA,// 发
                            BAI// 白
                    )
            );
        }
    },
    DA_SI_XI(13) {// 大四喜

        /**
         * 9番512分
         * 胡牌者完成东、南、西、北四组刻子
         * 三个东、西、南、北+任意一对
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {
            return MJBaseHuPaiRule.isDaSiXi(cards, getPaiXing());
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return new HashSet<>(
                    Arrays.asList(
                            DONG_FENG,// 东风
                            XI_FENG,// 西风
                            NAN_FENG,// 南风
                            BEI_FENG// 北风
                    )
            );
        }
    },
    SHI_SAN_YAO(14) {// 十三幺

        /**
         * 9番512分
         * 1、9万筒索，东、南、西、北、中、发、白；以上牌型任意一张牌作将
         * 一万、九万、一索、九索、一筒、九筒、东、西、南、北、中、发、白+任意
         * @param cards
         * @return
         */
        @Override
        public boolean checkHu(List<Card> cards) {

            return MJBaseHuPaiRule.isShiSanYao(cards, getPaiXing());
        }

        @Override
        public Set<CardSmallType> getPaiXing() {
            return new HashSet<>(
                    Arrays.asList(
                            YI_WAN,// 一万
                            JIU_WAN,// 九万
                            YI_SUO,// 一索
                            JIU_SUO,// 九索
                            YI_TONG,// 一筒
                            JIU_TONG,// 九筒
                            DONG_FENG,// 东风
                            XI_FENG,// 西风
                            NAN_FENG,// 南风
                            BEI_FENG,// 北风
                            ZHONG,// 中
                            FA,// 发
                            BAI// 白
                    )
            );
        }
    },
    ;


    private static Map<Integer, HandPattern> VALUES= Arrays.stream(HandPattern.values()).collect(Collectors.toMap(t->t.id,Function.identity()));
    HandPattern(int id){
        this.id=id;
    }
    public int id;
    public static boolean verfy(int id){
        return VALUES.containsKey(id);
    }
    public HandPattern get(int id){
        return VALUES.get(id);
    }

    public abstract boolean checkHu(List<Card> cards);
    public abstract Set<CardSmallType> getPaiXing();
}
